package com.witmore.neutron.ai.web.apiv2.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jk.common.response.ResponseResult;
import com.witmore.neutron.ai.db.entity.ModelConfigDO;
import com.witmore.neutron.ai.db.mapper.ModelConfigMapper;
import com.witmore.neutron.ai.web.annotation.NoLoginRequired;
import com.witmore.neutron.ai.web.annotation.RequiresPermission;
import com.witmore.neutron.ai.web.apiv2.controller.vo.ModelConfigGroupResult;
import com.witmore.neutron.ai.web.apiv2.controller.vo.ModelConfigResult;
import com.witmore.neutron.ai.web.apiv2.controller.vo.ModelConfigCreateParam;
import com.witmore.neutron.ai.web.apiv2.controller.vo.ModelConfigUpdateParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * V2 模型配置管理相关接口
 * Author: AI Assistant
 * Date: 2025/9/17
 */
@NoLoginRequired
@Slf4j
@RestController
@RequestMapping("/v2/model-config")
public class ModelConfigControllerV2 {

    @Autowired
    private ModelConfigMapper modelConfigMapper;

    /**
     * 查询模型配置列表（按类型分组）
     */
    @RequiresPermission("model:list")
    @GetMapping("/list")
    public ResponseResult<List<ModelConfigGroupResult>> getModelConfigList() {
        try {
            // 查询所有模型配置
            LambdaQueryWrapper<ModelConfigDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.orderByDesc(ModelConfigDO::getId);

            List<ModelConfigDO> modelConfigDOList = modelConfigMapper.selectList(queryWrapper);

            // 按model_type分组
            Map<String, List<ModelConfigDO>> groupedByType = modelConfigDOList.stream()
                    .collect(Collectors.groupingBy(
                            modelConfig -> StringUtils.hasText(modelConfig.getModelType()) ?
                                    modelConfig.getModelType() : "UNKNOWN"
                    ));

            // 转换为分组结果
            List<ModelConfigGroupResult> groupResultList = groupedByType.entrySet().stream()
                    .map(entry -> {
                        String modelType = entry.getKey();
                        List<ModelConfigDO> modelList = entry.getValue();

                        ModelConfigGroupResult groupResult = new ModelConfigGroupResult();
                        groupResult.setModelType(modelType);
                        groupResult.setModelTypeDesc(getModelTypeDesc(modelType));

                        // 转换为VO对象
                        List<ModelConfigResult> modelResultList = modelList.stream()
                                .map(this::convertToResult)
                                .collect(Collectors.toList());

                        groupResult.setModelList(modelResultList);
                        groupResult.setTotalCount(modelList.size());

                        // 统计启用的数量
                        long enabledCount = modelList.stream()
                                .filter(model -> Boolean.TRUE.equals(model.getEnabled()))
                                .count();
                        groupResult.setEnabledCount((int) enabledCount);

                        return groupResult;
                    })
                    .sorted((g1, g2) -> g1.getModelType().compareTo(g2.getModelType()))
                    .collect(Collectors.toList());

            return ResponseResult.success(groupResultList);
        } catch (Exception e) {
            log.error("查询模型配置列表失败", e);
            return ResponseResult.fail(500, "查询模型配置列表失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID查询模型配置详情
     */
    @RequiresPermission("model:detail")
    @GetMapping("/{id}")
    public ResponseResult<ModelConfigResult> getModelConfigById(@PathVariable("id") Integer id) {
        try {
            ModelConfigDO modelConfigDO = modelConfigMapper.selectById(id);
            if (modelConfigDO == null) {
                return ResponseResult.fail(404, "模型配置不存在");
            }

            ModelConfigResult result = convertToResult(modelConfigDO);
            return ResponseResult.success(result);
        } catch (Exception e) {
            log.error("查询模型配置详情失败, id: {}", id, e);
            return ResponseResult.fail(500, "查询模型配置详情失败: " + e.getMessage());
        }
    }

    /**
     * 新增模型配置
     */
    @RequiresPermission("model:create")
    @PostMapping("/create")
    public ResponseResult<ModelConfigResult> createModelConfig(@Valid @RequestBody ModelConfigCreateParam createParam) {
        try {
            // 检查模型名称是否已存在
            LambdaQueryWrapper<ModelConfigDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ModelConfigDO::getModelName, createParam.getModelName())
                       .eq(ModelConfigDO::getModelType, createParam.getModelType());

            ModelConfigDO existingModel = modelConfigMapper.selectOne(queryWrapper);
            if (existingModel != null) {
                return ResponseResult.fail(400, "该模型类型下已存在相同名称的模型配置");
            }

            // 创建新的模型配置
            ModelConfigDO modelConfigDO = new ModelConfigDO();
            BeanUtils.copyProperties(createParam, modelConfigDO);

            if (!StringUtils.hasText(createParam.getCompletionsPath())){
                modelConfigDO.setCompletionsPath("/v1/completions");
            }
            // 设置默认值
            if (modelConfigDO.getSessionCostCount() == null) {
                modelConfigDO.setSessionCostCount(1);
            }
            // 如果没有提供支持功能配置，设置默认JSON配置
            if (!StringUtils.hasText(modelConfigDO.getSupportedCapability())) {
                String defaultCapability = "{\"image_recognition\":false,\"image_format\":\"jpeg/jpg/png\",\"plugin_support\":true,\"file_upload\":false,\"file_format\":\"doc/docx/xls/xlsx/pdf/ppt/pptx/txt\"}";
                modelConfigDO.setSupportedCapability(defaultCapability);
            }

            int result = modelConfigMapper.insert(modelConfigDO);
            if (result > 0) {
                ModelConfigResult responseResult = convertToResult(modelConfigDO);
                log.info("成功创建模型配置，ID: {}, 模型名称: {}", modelConfigDO.getId(), createParam.getModelName());
                return ResponseResult.success(responseResult);
            } else {
                return ResponseResult.fail(500, "创建模型配置失败");
            }
        } catch (Exception e) {
            log.error("创建模型配置失败", e);
            return ResponseResult.fail(500, "创建模型配置失败: " + e.getMessage());
        }
    }

    /**
     * 修改模型配置
     */
    @RequiresPermission("model:update")
    @PostMapping("/update")
    public ResponseResult<ModelConfigResult> updateModelConfig(@Valid @RequestBody ModelConfigUpdateParam updateParam) {
        try {
            // 检查模型配置是否存在
            ModelConfigDO existingModel = modelConfigMapper.selectById(updateParam.getId());
            if (existingModel == null) {
                return ResponseResult.fail(404, "模型配置不存在");
            }

            // 如果修改了模型名称或类型，检查是否与其他模型重复
            if ((StringUtils.hasText(updateParam.getModelName()) && !updateParam.getModelName().equals(existingModel.getModelName())) ||
                (StringUtils.hasText(updateParam.getModelType()) && !updateParam.getModelType().equals(existingModel.getModelType()))) {

                String modelName = StringUtils.hasText(updateParam.getModelName()) ? updateParam.getModelName() : existingModel.getModelName();
                String modelType = StringUtils.hasText(updateParam.getModelType()) ? updateParam.getModelType() : existingModel.getModelType();

                LambdaQueryWrapper<ModelConfigDO> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ModelConfigDO::getModelName, modelName)
                           .eq(ModelConfigDO::getModelType, modelType)
                           .ne(ModelConfigDO::getId, updateParam.getId());

                ModelConfigDO duplicateModel = modelConfigMapper.selectOne(queryWrapper);
                if (duplicateModel != null) {
                    return ResponseResult.fail(400, "该模型类型下已存在相同名称的模型配置");
                }
            }

            // 构建更新条件，只更新非空字段
            LambdaUpdateWrapper<ModelConfigDO> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(ModelConfigDO::getId, updateParam.getId());

            // 动态设置更新字段
            updateWrapper
                .set(StringUtils.hasText(updateParam.getChatClientType()), ModelConfigDO::getChatClientType, updateParam.getChatClientType())
                .set(StringUtils.hasText(updateParam.getModelManufacturer()), ModelConfigDO::getModelManufacturer, updateParam.getModelManufacturer())
                .set(StringUtils.hasText(updateParam.getModelName()), ModelConfigDO::getModelName, updateParam.getModelName())
                .set(StringUtils.hasText(updateParam.getModelApikey()), ModelConfigDO::getModelApikey, updateParam.getModelApikey())
                .set(StringUtils.hasText(updateParam.getModelApiid()), ModelConfigDO::getModelApiid, updateParam.getModelApiid())
                .set(StringUtils.hasText(updateParam.getModelEndpoint()), ModelConfigDO::getModelEndpoint, updateParam.getModelEndpoint())
                .set(StringUtils.hasText(updateParam.getCompletionsPath()), ModelConfigDO::getCompletionsPath, updateParam.getCompletionsPath())
                .set(updateParam.getEnabled() != null, ModelConfigDO::getEnabled, updateParam.getEnabled())
                .set(StringUtils.hasText(updateParam.getSupportedCapability()), ModelConfigDO::getSupportedCapability, updateParam.getSupportedCapability())
                .set(StringUtils.hasText(updateParam.getModelType()), ModelConfigDO::getModelType, updateParam.getModelType())
                .set(updateParam.getSessionCostCount() != null, ModelConfigDO::getSessionCostCount, updateParam.getSessionCostCount());

            int result = modelConfigMapper.update(null, updateWrapper);
            if (result > 0) {
                // 重新查询更新后的数据
                ModelConfigDO updatedModel = modelConfigMapper.selectById(updateParam.getId());
                ModelConfigResult responseResult = convertToResult(updatedModel);
                log.info("成功更新模型配置，ID: {}", updateParam.getId());
                return ResponseResult.success(responseResult);
            } else {
                return ResponseResult.fail(500, "更新模型配置失败");
            }
        } catch (Exception e) {
            log.error("更新模型配置失败，ID: {}", updateParam.getId(), e);
            return ResponseResult.fail(500, "更新模型配置失败: " + e.getMessage());
        }
    }

    /**
     * 将DO对象转换为Result对象
     */
    private ModelConfigResult convertToResult(ModelConfigDO modelConfigDO) {
        ModelConfigResult result = new ModelConfigResult();
        BeanUtils.copyProperties(modelConfigDO, result);
        return result;
    }

    /**
     * 获取模型类型描述
     */
    private String getModelTypeDesc(String modelType) {
        if (!StringUtils.hasText(modelType)) {
            return "未知类型";
        }

        return switch (modelType.toUpperCase()) {
            case "TONG_YI" -> "通义千问";
            case "HUN_YUAN" -> "腾讯混元";
            case "OPENAI" -> "OpenAI";
            case "AZURE" -> "Azure OpenAI";
            case "OTHERS" -> "其他模型";
            default -> modelType;
        };
    }

}
